package logic;

import gui.DefeatScreen;
import gui.VictoryScreen;

/**
 * class representing multi player engine
 * @author Rekin
 *
 */
public class EngineBluetoothGame extends Engine{
	private BluetoothCommunicationHandler btcom;
	private boolean hasToken;
	
	/**
	 * @param com handler for bluetooth communication
	 * @param temp settings for engine
	 */
	public EngineBluetoothGame(BluetoothCommunicationHandler com,
			TempUserSettings temp){
		super(temp);
		if(com.isServer()){
			hasToken=true;
		}
		else{
			hasToken=false;
		}
		canSave=false;
		initPlayers();
		btcom=com;
		btcom.setEngine(this);
		btcom.startRetrieving();
	}

	/**
	 * @return handler for bluetooth communication
	 */
	public BluetoothCommunicationHandler getBtcom() {
		return btcom;
	}

	/**
	 * @param btcom handler for bluetooth communication
	 */
	public void setBtcom(BluetoothCommunicationHandler btcom) {
		this.btcom = btcom;
	}
	
	/**
	 * closes bluetooth connection
	 */
	public void closeConnections(){
		btcom.closeConnections();
	}
	
	/**
	 * sets remote player name
	 * @param remotePlayerName name of remote player
	 */
	public void saveReceivedPlayerData(String remotePlayerName){
		players[1].setName(remotePlayerName);
		System.out.println("Received name:"+remotePlayerName);
	}
	
	/**
	 * initiates players 
	 * super class logic - should be overriden
	 */
	protected void initPlayers(){
		players=new Player[playerNumber];
		for(int i=0;i<playerNumber;++i){
			players[i]=new Player(getStartingMoney());
			players[i].setName("Player"+(i+1));
			players[i].initCards(cardDeck);
		}
		players[0].setName(predefinedSettings.getPlayerName());
	}
	
	/**
	 * handles after buttons click logic
	 * super class logic - should be overriden
	 * @param pressedButton button that was hit
	 */
	public void doLogic(int pressedButton){
		System.out.println("Bluetooth Engine - doLogic(int) ="+pressedButton);
		if(!hasToken){
			return;
		}
		
		switch(pressedButton){
			case LogicHelper.pressButtonCall:
				if(btcom.isServer()){
					moneyOnBoard+=defaultStake;
					players[0].substractMoney(defaultStake);
					if(currentRound==3){
						btcom.sendMessage(""+NetMessage.ACCEPT_DOUBLE+NetMessage.SEPARATOR);
						players[0].cardSort();
						players[0].countCards();
						players[1].cardSort();
						players[1].countCards();
						roundWinner = whoWon();
						winnerName = players[roundWinner].getName();
						//send winner and his sequence
						btcom.sendMessage(""+NetMessage.SERVER_WHO_WON+NetMessage.SEPARATOR+roundWinner+"_"+players[0].getSeqTxt());
						++currentRound;
						hasToken=true;
						MainMidlet.getMidletInstance().getBoard().doMultiplayerRevalidate();
						return;
					}
					else{
						btcom.sendMessage(""+NetMessage.ACTION_BUTTON+NetMessage.SEPARATOR+LogicHelper.pressButtonCall);
					}
				}
				else{
					moneyOnBoard+=currentStake; //single or double
					players[0].substractMoney(currentStake);
					if(currentRound==2){
						++currentRound; //you call for server single or double stake - go to final round
					}
					btcom.sendMessage(""+NetMessage.ACTION_BUTTON+NetMessage.SEPARATOR+LogicHelper.pressButtonCall);
				}
				break;
			case LogicHelper.pressButtonExchange:
				if(btcom.isServer()){
					players[0].exchangeCards(cardDeck);
					MainMidlet.getMidletInstance().getBoard().resetCardsToStartingPosition();
					MainMidlet.getMidletInstance().getBoard().newSpritesImages();
					btcom.sendMessage(""+NetMessage.ACTION_BUTTON+NetMessage.SEPARATOR+LogicHelper.pressButtonExchange);
				}
				else{
					btcom.sendSelectedClientCards();
				}
				break;
			case LogicHelper.pressButtonDouble:
				currentStake*=2;
				moneyOnBoard+=currentStake;
				players[0].substractMoney(currentStake);
				++currentRound; //there won't be extra round
				btcom.sendMessage(""+NetMessage.ACTION_BUTTON+NetMessage.SEPARATOR+LogicHelper.pressButtonDouble);
				break;
			case LogicHelper.pressButtonDrop:
				players[0].setInGame(false);
				if(btcom.isServer()){
					currentRound=4; 
					roundWinner = 1;
					winnerName = players[roundWinner].getName();
					btcom.sendMessage(""+NetMessage.ACTION_BUTTON+NetMessage.SEPARATOR+LogicHelper.pressButtonDrop);
					MainMidlet.getMidletInstance().getBoard().doMultiplayerRevalidate();
					return;
				}
				else{
					currentRound=3; 
					roundWinner = 1;
					winnerName = players[roundWinner].getName();
					btcom.sendMessage(""+NetMessage.ACTION_BUTTON+NetMessage.SEPARATOR+LogicHelper.pressButtonDrop);
				}
				break;
			case LogicHelper.pressButtonNext:
				currentRound=-1;
				currentStake=defaultStake;
				players[roundWinner].addMoney(moneyOnBoard);
				if(players[0].getMoney()<=defaultEntryFee){
					btcom.sendMessage(""+NetMessage.ACTION_FINAL+NetMessage.SEPARATOR+"1");
					MainMidlet.getMidletInstance().setDisplay(new DefeatScreen());
					return;
				}
				else if(players[1].getMoney()<=defaultEntryFee){
					btcom.sendMessage(""+NetMessage.ACTION_FINAL+NetMessage.SEPARATOR+"0");
					MainMidlet.getMidletInstance().setDisplay(new VictoryScreen());
					return;
				}
				moneyOnBoard=0;
				roundWinner=-1;
				winnerName="";
				players[0].resetPlayerForNewRound();
				players[1].resetPlayerForNewRound();
				if(btcom.isServer()){
					initCardDeck();
					players[0].initCards(cardDeck);
					players[1].initCards(cardDeck);
				}
				takeEntryFee();
				
				if(btcom.isServer()){
					btcom.sendCardsToOtherPlayerCom();
				}
				else{
					btcom.setPlayerCardsFromRemoteData(btcom.getPlayerCardsForNextRound(), players[0]);
					btcom.setPlayerCardsForNextRound("");
					for(int i=0;i<5;++i){
						players[0].getCard(i).setSelected(false);
					}
					//refresh cards but don't allow to move yet
					MainMidlet.getMidletInstance().getBoard().resetCardsToStartingPosition();
					MainMidlet.getMidletInstance().getBoard().newSpritesImages();
					btcom.sendMessage(""+NetMessage.ACTION_BUTTON+NetMessage.SEPARATOR+LogicHelper.pressButtonNext);
				}
				break;
			default:
				break;
		}
		
		++currentRound;
		hasToken=false;
		MainMidlet.getMidletInstance().getBoard().doMultiplayerRevalidate();
		
	}
	
	/**
	 * handles receiving buttons click logic
	 * @param receivedButton button that was hit by remote user and received via bluetooth
	 */
	public void doReceiveLogic(int receivedButton){
		System.out.println("Bluetooth Engine - doReceiveLogic(int) ="+receivedButton);
		
		switch(receivedButton){
			case LogicHelper.pressButtonCall:
				if(btcom.isServer()){
					players[1].substractMoney(currentStake);
					moneyOnBoard+=currentStake;
					if(currentRound==3){ //if client didn't doubled in his round 2, we don't enter round 3, but go to final
						++currentRound;
					}
				}
				else{
					players[1].substractMoney(defaultStake);
					moneyOnBoard+=defaultStake;
				}
				break;
			case NetMessage.TOKEN:
			case LogicHelper.pressButtonExchange:
				break;
			case LogicHelper.pressButtonDouble:
				if(btcom.isServer()){
					// we gave single stake, but player 2 gave double - we have to stay in round 3
					currentStake*=2;
					players[1].substractMoney(currentStake);
					moneyOnBoard+=currentStake;
				}
				else{
					currentStake*=2;
					players[1].substractMoney(currentStake);
					moneyOnBoard+=currentStake;
				}
				break;
			case LogicHelper.pressButtonDrop:
				if(btcom.isServer()){
					currentRound=4; 
					roundWinner = 0;
					winnerName = players[roundWinner].getName();
					players[1].setInGame(false);
					hasToken=true;
					MainMidlet.getMidletInstance().getBoard().doMultiplayerRevalidate();
					return;
				}
				else{
					currentRound=4; 
					roundWinner = 0;
					winnerName = players[roundWinner].getName();
					players[1].setInGame(false);
					hasToken=false;
					MainMidlet.getMidletInstance().getBoard().doMultiplayerRevalidate();
					return;
				}
			case LogicHelper.pressButtonNext:
				if(btcom.isServer()){
				}
				else{
				}
				break;
			default:
				break;
		}
		
		if(currentRound==4){
			if(btcom.isServer()){
				players[0].cardSort();
				players[0].countCards();
				players[1].cardSort();
				players[1].countCards();
				roundWinner = whoWon();
				winnerName = players[roundWinner].getName();
				//send winner and his sequence
				btcom.sendMessage(""+NetMessage.SERVER_WHO_WON+NetMessage.SEPARATOR+roundWinner+"_"+players[0].getSeqTxt());
			}
		}
		
		hasToken=true;
		MainMidlet.getMidletInstance().getBoard().doMultiplayerRevalidate();

	}

	/**
	 * @return if has token (client or server move at once)
	 */
	public boolean hasToken() {
		return hasToken;
	}

	/**
	 * @param hasToken token indicating that the player has now time to move
	 */
	public void setHasToken(boolean hasToken) {
		this.hasToken = hasToken;
	}
	
}
